<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
   <script type="text/javascript">
    /*
       总结
        1.类中的构造器不是必须写的，要对实例进行一些初始化的操作，如添加指定属性时才写。
        2.如果a类继承了b类，且a类写了构造器，那么a类中的super（）是必须要调用的
        3.类中定义的方法都是放在了类的原型对象上，供实例去使用
    
    */
    // 创建一个Person类
    class Person {
      // 构造器方法，通过构造器把属性放到实例的自身
      constructor(name, age) {
        // 构造器中的this时类的实例对象
        this.name = name;
        this.age =age;
        // 写了一个school属性，所有的实例school都是家里蹲
        this.school = "家里蹲"
      }
      // 一般方法 思考speak方法放到了哪里--类的原型对象上—__proto__
      // 放到原型对象上的方法是给实例用的
      // 通过person实例调用speak时，speak中的this就是person实例
      speak() {
        console.log(`我叫${this.name},我的年龄是${this.age}`);
      }
    }
    
    // 创建一个student类，继承person
    class Student extends Person {
      constructor(name,age,grade) {
        // super帮我们调用父类的构造器, name,age属性必须写，super里面也要加上name,age
        super(name,age)
        this.grade = grade
      }
      // 重写从父类继承过来的方法
      speak() {
        console.log(`我叫${this.name},我的年龄是${this.age},我读的是${this.grade}`);
      }
      study() {
        console.log('我很努力的学习');
      }

    }
    // 构造器都可以继承父类，如果子类想有独有的属性那我们就要写构造器了
    const s1 = new Student('xiaozhang', 15, '高一')
    console.log(s1);
   </script>
</body>
</html>